#include <Ogre.h>

#include "IntroState.h"
#include "InstructionState.h"
#include "OptionsState.h"
#include "NetworkState.h"

using namespace Ogre;

IntroState IntroState::mIntroState;

IntroState::IntroState()
{
	mWindow = 0;
	mDebugOverlay = 0;
	displayCameraDetails = false;
	statsOn = false;
	mTimeUntilNextToggle = 0.0f;
}

void IntroState::enter()
{
	mRoot = Root::getSingletonPtr();
	mWindow = mRoot->getAutoCreatedWindow();
	mDeviceManager = DeviceManager::getSingletonPtr();
	mDeviceManager->setBuffered(true);	// Sets input devices to buffered mode
	mGUIManager = GUIManager::getSingletonPtr();
	mKeyboard = mDeviceManager->mKeyboard;
	mMouse = mDeviceManager->mMouse;

	// Set up Debug Overlay
	mDebugOverlay = OverlayManager::getSingleton().getByName("Core/DebugOverlay");

	// Create SceneManager	
	mSceneMgr = mRoot->getSceneManager("plitzScene");

	// Create Camera
	mCamera = mSceneMgr->createCamera("IntroCamera");

	// Create Viewport
	mViewport = mRoot->getAutoCreatedWindow()->addViewport(mCamera);
	mViewport->setBackgroundColour(ColourValue(0.0, 0.0, 0.0));

	// Create Sprite Manager
	//spriteManager=new Ogre2dManager;
	//spriteManager->init(mSceneMgr, Ogre::RENDER_QUEUE_OVERLAY, true);

	// Load Background
	MaterialPtr material = MaterialManager::getSingleton().getByName("PlitzBack");
	Rectangle2D* rect = new Rectangle2D(true);
	double x1 = (190-512.0f)/512.0f;
	double y1 = (368.0f-70)/368.0f;
	double x2 = (830-512.0f)/512.0f;
	double y2 = (368.0f-470)/368.0f;
	rect->setCorners(x1, y1, x2, y2);
	rect->setMaterial(material->getName());
	// Render the background before everything else
	rect->setRenderQueueGroup(RENDER_QUEUE_BACKGROUND);
	AxisAlignedBox aabInf;
	aabInf.setInfinite();
	rect->setBoundingBox(aabInf);
	// Attach background to the scene
	SceneNode* node = mSceneMgr->getRootSceneNode()->createChildSceneNode("PlitzBackNode");
	node->attachObject(rect);

	// Create Sound Manager
	soundManager = OgreAL::SoundManager::getSingletonPtr();
	
	// Playing music
	sound = soundManager->createSound("MenuTheme", "MenuTheme.ogg", true);
	sound->setGain(Config::BGSOUNDLEVEL);
	sound->play();

	// Reigster GUI Items
	mGUIManager->registerScene(mSceneMgr);
	mGUIManager->setGUISheet(CEGUI::WindowManager::getSingletonPtr()->getWindow("Intro/Sheet"));
	setupEventHandlers();

	// Set default values for each entry
	mExitGame = false;
	mGoToNet = false;
	mGoOptions = false;
	mGoInstruction = false;
}

void IntroState::exit()
{
	// Clean up sprite manager
	//spriteManager->end();
	//delete spriteManager;

	// Clean up the sound
	sound->stop();
	soundManager->destroySound(sound);
	

	// Switch off debug overlays
	displayCameraDetails = false;
	statsOn = false;
	mDebugOverlay->hide();

	// Clean up scene
	mSceneMgr->clearScene();
	mSceneMgr->destroyAllCameras();
	mRoot->getAutoCreatedWindow()->removeAllViewports();
}

void IntroState::pause()
{
}

void IntroState::resume()
{
}

bool IntroState::keyPressed(const OIS::KeyEvent &arg)
{
	if (arg.key == OIS::KC_P)	// GUI Text says play but goes to NETSTATE not PLAYSTATE
		mGoToNet = true;
	if (arg.key == OIS::KC_Q || arg.key == OIS::KC_ESCAPE)
		mExitGame = true;
	if (arg.key == OIS::KC_I)
		mGoInstruction = true;
	if (arg.key == OIS::KC_O)
		mGoOptions = true;
	
	// Take Screen Shot
	if (arg.key == OIS::KC_SYSRQ && mTimeUntilNextToggle <= 0)
	{
		mWindow->writeContentsToTimestampedFile("Plitzkrieg",".jpg");
		mTimeUntilNextToggle = 0.5;
	}

	// Toggle Debug Overlay
	if (arg.key == OIS::KC_F1 && mTimeUntilNextToggle <= 0 && Config::getInstance()->cfg_debugOn)
	{
		statsOn = !statsOn;
		mTimeUntilNextToggle = 0.5;
		if (statsOn) mDebugOverlay->show();
		else mDebugOverlay->hide();
	}

	return true;
}

bool IntroState::keyReleased(const OIS::KeyEvent &arg)
{
	return true;
}

bool IntroState::mouseMoved( const OIS::MouseEvent &arg )
{
	CEGUI::System::getSingleton().injectMouseMove( arg.state.X.rel, arg.state.Y.rel );
	mDeviceManager->mMouseCursor->updatePosition(arg.state.X.abs,arg.state.Y.abs);
	return true;
}

bool IntroState::mousePressed( const OIS::MouseEvent &arg, OIS::MouseButtonID id )
{
	CEGUI::System::getSingleton().injectMouseButtonDown(convertOISMouseButtonToCegui(id));
	return true;
}

bool IntroState::mouseReleased( const OIS::MouseEvent &arg, OIS::MouseButtonID id )
{
	CEGUI::System::getSingleton().injectMouseButtonUp(convertOISMouseButtonToCegui(id));
	return true;
}

bool IntroState::frameStarted(const FrameEvent& evt)
{
	// Update toggle buffering time
	if (mTimeUntilNextToggle >= 0)
				mTimeUntilNextToggle -= evt.timeSinceLastFrame;

	// Updating debug overlay stats
	updateStats();

	drawSprites();

	if (mKeyboard) 
		mKeyboard->capture();
	if (mMouse)
		mMouse->capture();
	return true;
}

bool IntroState::frameEnded(const FrameEvent& evt)
{
	if (mExitGame)
		return false;
	if (mGoToNet)
		changeState(NetworkState::getInstance());
	if (mGoOptions)
		changeState(OptionsState::getInstance());
	if (mGoInstruction)
		changeState(InstructionState::getInstance());
	return true;
}

void IntroState::createScene()
{
}

void IntroState::setupEventHandlers()
{
	CEGUI::WindowManager *wmgr = CEGUI::WindowManager::getSingletonPtr();
	CEGUI::Window *play = wmgr->getWindow((CEGUI::utf8*)"Intro/PlayButton");
	play->subscribeEvent(CEGUI::PushButton::EventClicked, CEGUI::Event::Subscriber(&IntroState::handlePlay, this));
	CEGUI::Window *instr = wmgr->getWindow((CEGUI::utf8*)"Intro/InstructionButton");
	instr->subscribeEvent(CEGUI::PushButton::EventClicked, CEGUI::Event::Subscriber(&IntroState::handleInstruction, this));
	CEGUI::Window *options = wmgr->getWindow((CEGUI::utf8*)"Intro/OptionsButton");
	options->subscribeEvent(CEGUI::PushButton::EventClicked, CEGUI::Event::Subscriber(&IntroState::handleOptions, this));
    CEGUI::Window *quit = wmgr->getWindow((CEGUI::utf8*)"Intro/QuitButton");
	quit->subscribeEvent(CEGUI::PushButton::EventClicked, CEGUI::Event::Subscriber(&IntroState::handleQuit, this));
}

bool IntroState::handleQuit(const CEGUI::EventArgs& e)
{
	mExitGame = true;
	return true;
}

bool IntroState::handlePlay(const CEGUI::EventArgs& e)
{
	mGoToNet = true;
	return true;
}

bool IntroState::handleOptions(const CEGUI::EventArgs& e)
{
	mGoOptions = true;
	return true;
}

bool IntroState::handleInstruction(const CEGUI::EventArgs& e)
{
	mGoInstruction = true;
	return true;
}

void IntroState::drawSprites()
{
//	spriteManager->drawSprite("plitzkrieg1.png", 190,70,830,470);
}